<?php

namespace App\Http\Controllers\DataV;

use App\Exceptions\BusinessException;
use App\Http\Controllers\Controller;
use App\Models\DataVUserModel;
use App\Models\OrderModel;
use App\Models\UserModel;
use App\Utils\ApiResponse;
use App\Utils\VerifyRequestInput;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Carbon\Carbon;

class DataVController extends Controller
{
    use ApiResponse, VerifyRequestInput;

    /**
     * 订单汇总卡片数据
     * @return JsonResponse
     */
    public function getDashboardCardData(): JsonResponse
    {
        $item = DataVUserModel::selectRaw('SUM(order_number) AS order_number,SUM(order_total) AS order_total')->first();
        $today = OrderModel::where('pay_status', 1)->where('goods_total', '>', 0)->whereDate('created_at', Carbon::today()->toDateString())
            ->selectRaw('COUNT(id) AS order_number, SUM(goods_total) AS order_total')->first();
        return $this->success([
            ['text' => '今日订单数', 'value' => $today->order_number],
            ['text' => '今日订单金额', 'value' => $today->order_total],
            ['text' => '累计订单数', 'value' => $item->order_number + $today->order_number],
            ['text' => '累计订单金额', 'value' => $item->order_total + $today->order_total]
        ]);
    }

    /**
     * 用户和订单数据汇总
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function getDateSumList(Request $request): JsonResponse
    {
        $this->verifyString('period');
        $date = $request->input('date');
        if (!is_array($date))
            $date = explode(',', $date);
        if ($request->input('period') === 'dateRange') {
            $collection = DataVUserModel::whereBetween('date', $date)
                ->select(['date', 'register_user_number', 'order_user_number', 'order_number',
                    'order_total', 'new_order_number', 'new_order_total'])->orderBy('date')->get();
            return $this->success($collection);
        } else {
            $list = $this->getMonthRangeData($date);
            return $this->success($list);
        }
    }

    /**
     * 自动统计每日订单数据
     * @return void
     */
    public function autoGetDayNewUserData(): void
    {
        $date = DataVUserModel::orderByDesc('id')->value('date');
        $queryDate = $date ? Carbon::parse($date)->addDays(1)->toDateString() : '2022-10-01';
        if (Carbon::parse($queryDate)->lt(Carbon::today())) {
            $userListData = UserModel::whereDate('created_at', $queryDate)->pluck('id')->toArray();
            $totalItem = OrderModel::where('pay_status', 1)->where('goods_total', '>', 0)->whereDate('created_at', $queryDate)
                ->selectRaw('COUNT(id) AS order_number, SUM(goods_total) AS order_total')->first();
            $newTotalItem = OrderModel::where('pay_status', 1)->where('goods_total', '>', 0)->whereDate('created_at', $queryDate)
                ->whereIn('uid', $userListData)->selectRaw('COUNT(id) AS new_order_number, SUM(goods_total) AS new_order_total')->first();
            $newOrderUserListData = OrderModel::where('pay_status', 1)->where('goods_total', '>', 0)->whereDate('created_at', $queryDate)
                ->distinct('uid')->pluck('uid')->toArray();
            DataVUserModel::create([
                'date'                  => $queryDate,
                'register_user_number'  => count($userListData),
                'order_user_number'     => $this->getNewOrderUserCount($userListData, $newOrderUserListData),
                'order_number'          => $totalItem ? intval($totalItem->order_number) : 0,
                'order_total'           => $totalItem ? floatval($totalItem->order_total) : 0,
                'new_order_number'      => $newTotalItem ? intval($newTotalItem->new_order_number) : 0,
                'new_order_total'       => $newTotalItem ? floatval($newTotalItem->new_order_total) : 0
            ]);
        }
    }

    /**
     * 获取每月用户和订单数据汇总
     * @param $date
     * @return array
     */
    private function getMonthRangeData($date): array
    {
        $dateList = $this->getMonthList($date);
        $list = [];
        foreach ($dateList as $monthPeriod) {
            $item = DataVUserModel::whereBetween('date', $monthPeriod)
                ->selectRaw(
                    'SUM(register_user_number) AS register_user_number,
                         SUM(order_user_number) AS order_user_number,
                         SUM(order_number) AS order_number,
                         SUM(order_total) AS order_total,
                         SUM(new_order_number) AS new_order_number,
                         SUM(new_order_total) AS new_order_total')->first();
            if ($item) {
                $item->date = substr($monthPeriod[0], 0, 7);
                $list[] = $item;
            }
        }
        return $list;
    }

    /**
     * 获取新增下单用户数
     * @param $userList
     * @param $orderUserList
     * @return int
     */
    private function getNewOrderUserCount($userList, $orderUserList): int
    {
        $data = [];
        if (count($userList) && count($orderUserList)) {
            foreach ($orderUserList as $uid) {
                if (in_array($uid, $userList))
                    $data[] = $uid;
            }
            return count($data);
        } else
            return 0;
    }

    /**
     * 获取月份列表
     * @param $date
     * @return array
     */
    private function getMonthList($date): array
    {
        $start = Carbon::parse($date[0]);
        $end = Carbon::parse($date[1]);
        $monthNumber = 1;
        $list = [];
        while ($start->lte($end)) {
            $list[] = [$start->toDateString(), $start->endOfMonth()->toDateString()];
            $start = Carbon::parse($date[0])->addMonths($monthNumber);
            $monthNumber++;
        }
        return $list;
    }
}
